/*
    文件内容: 封装EventLoop相关操作,封装Epoll,和while循环
    文件名: EventLoop.h
    作者: 中国好青年(码农论坛)
    时间: 2024/9/6

*/
#pragma once
#include "Epoll.h"
#include <functional>
#include <memory>
#include <queue>
#include <mutex>
#include <sys/eventfd.h>
#include <unistd.h>
#include <sys/syscall.h>   /* For SYS_xxx definitions */
#include <sys/timerfd.h> 
#include <map>
#include "Connection.h"
#include <atomic>

class Connection;
class Epoll;
class Channel;
using spConnection = std::shared_ptr<Connection>;

/*
    类名: EventLoop
    作用: 封装EventLoop相关操作类,封装主函数while循环和Epoll
*/
class EventLoop
{
private:
    /* 成员变量 */
    std::unique_ptr<Epoll> ep_;
    int wakeupfd_; // eventfd
    int timerfd_;   // timerfd
    int epolltimeoutval_;
    bool mainloop_;
    int timeout_; //超时时间
    int timerval_; //定时器间隔
    std::mutex mutex_;
    pid_t curlooppid_;
    std::atomic<bool> stop_;//事件循环停止标志位
    std::unique_ptr<Channel> wakeupchannel_;
    std::unique_ptr<Channel> timerchannel_;
    std::queue<std::function<void()>> taskqueue_;
    std::map<int,spConnection> conns;
    /* function对象 函数对象 */
    std::function<void(EventLoop*)> epolltimeoutcallback_;
    std::function<void(int)> timercallback_;

private:
    int createTimerFD(int timeout = 5);

public:
    /* 构造函数 和 析构函数 */
    EventLoop(bool mainloop, int timeout, int timerval);
    ~EventLoop();

    /* EventLoop相关操作函数 */
    void run();
    void stop();

    void updateChannel(Channel *ch);
    void removeChannel(Channel *ch);
    bool isEqualPid();
    void addTaskQueue(std::function<void()> fn);
    void wakeup();
    void handleWakeup();
    void handleTimer();
    void newconnection(spConnection conn);

    void setEpollTimeoutVal(int timeout);
    void setepolltimeoutcallback(std::function<void(EventLoop*)> epolltimeoutcallback);
    void setTimerCallback(std::function<void(int)> timercallback);
};